/* 	Print2.c
	MPW Tool to print two pages per page
	Copyright Fred A. Huxham 1988
	
	Additional Options:
	
	-3				Flip page for 3-hole punched paper
	
	This tool supports the same printing options as the standard MPW Print tool
	except for the following:
	
	-ff string		Form feed string.
	-from n			Print pages starting from page number n.
	-l[ines] n		Print (at most) n lines per page.
	-ls n			Set line spacing.
	-n				Turn on line numbering.
	-nw				Width of the line number field in characters.
	-page n			Number the pages of the file, beginning with n.
	-q quality		Set print quality on the ImageWriter
	-r				Output pages to the printer in reverse order.
	-title name		If printing page headers, use name as the title.
	-to n			Print pages up to page n.
	-tm n			Top margin
	-bm n			Bottom margin
	-lm n			Left margin
	-rm n			Right margin
	
	I didn't implement these options for two reasons:
	
	1. I don't use them.
	2. I'm lazy.
	
	Revision History:
	
	07/14/88	FAH		File created
	07/25/88	FAH		1.0A1 All the options that I ever use are complete.
	07/26/88	FAH		Fixed a bug in DrawBorder where I wasn't checking to
						see if the user had selected the option to DrawHeaders or not.
						Created a routine, DoAbout so that multiple -p options would
						not cause the about string to be printed multiple times.
	08/04/88	DJB		Various bug fixes, and added 3 Hole option (-3).
	09/08/88	DJB		Fixed 3 Hole printing.
						Fixed overrun of Date/Time, Filename, Page Number in header
						Clear and restore FScaleDisable, for MPW 3.0b1
						Switched from TN#149 to jamming PrintRecord to set document name
						(Added 20% slack feature for Mercer)
	09/16/88	DJB		Fixed bug in overrun of Date/Time, Filename, Page Number in header
						Set minimum font size to 3pt for Phil
	
*/
#define DEBUG

#include	<types.h>
#include	<stdlib.h>
#include	<stdio.h>
#include	<fcntl.h>
#include	<ioctl.h>
#include	<cursorctl.h>
#include	<quickdraw.h>
#include	<resources.h>
#include	<memory.h>
#include	<files.h>
#include	<string.h>
#include	<strings.h>
#include	<errmgr.h>
#include	<errors.h>
#include	<fonts.h>
#include	<printtraps.h>
#include	<packages.h>
#include	<toolutils.h>
#include	<osutils.h>
#include	<ctype.h>

/*-------------------------------------------------------------------------------------------------*/
/* Type definitions */
typedef struct Header {
	short	font;
	short	size;
	short	height;
	Boolean	draw;
	Boolean	modDate;
	char	*title;
	char	date[256];
	char	time[256];
} Header;

typedef struct Body {
	short	font;
	short	size;
	short	tabWidth;
	short	lineHeight;
	short	linesPerPage;
	short	borderType;
} Body;

/* Globals */
THPrint		thePrintRec;
TPPrPort	thePrPort;
Handle 		jobNameH = nil;
Header		theHeader;
Body		theBody;
short		numCopies = 1;
short		cmdLineTab = 9999;
short		cmdLineFont = 9999;
short		cmdLineSize = 0;
Boolean		printProgress = false;
Boolean		threeHole = false;
Boolean		slack = true;
WindowPtr	phonyWindow = nil;

/* Enumeration constants */
enum sides {left,right};

/* Defines */
#define	maxStr	512

/* Function prototypes */
void	SetDefaults();
void	DoAbout();
void 	SetFileStuff(char *fileName);
Rect	GetrPage(THPrint thePrintRec);
void	ForceLandscape(THPrint thePrintRec);
void	DrawHeader(Rect *theRect,short pageNum);
Rect	DrawBorder(short whichSide,short pageNum);
short	Tabs2Spaces(char *theString);
OSErr	PrintFile(FILE *theStream);
int		SetOptions(int argc, char *argv[],short *files);
void	PrValidateAndName(THPrint tPR, char *fname);
int		main(int argc, char *argv[]);
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Set the default values for the globals */
void SetDefaults()
{
	theHeader.font = times;
	theHeader.size = 8;
	theHeader.height = 0;
	theHeader.draw = false;
	
	theBody.font = courier;
	theBody.size = 6;
	theBody.tabWidth = 4;
	theBody.borderType = 0;
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Prints the about string to standard out (for the -p option) */
void DoAbout()
{
	char	*about = "\nPrint2 (Version 1.0B1 September 8, 1988) - (c) 1988 Fred A. Huxham\n"
					 "         (Modifications and minor bug fixes by  -  Dave Burnard)\n";

	fprintf(stdout,about);
	fflush(stdout);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* This routine does a few different things.  First, set the header title to the
	filename.  Then set the header date to either the file's last modification date/time
	or the current date/time, depending on the theHeader.modDate flag.  Next, set the
	font, size and tab values for the print job according to the following,
		1.  Get the values from the command line.
		2.  Get the values from the resource fork of the file (only if MPW text files)
		3.  Use the defaults.
*/
void SetFileStuff(char *fileName)
{
	unsigned long	temp, result;
	long	temp1;
	ParamBlockRec	thePB;
	
	theHeader.title = fileName;
	
	if(theHeader.modDate) {
		thePB.fileParam.ioCompletion = 0;
		thePB.fileParam.ioNamePtr = c2pstr(fileName);
		thePB.fileParam.ioVRefNum = 0;
		thePB.fileParam.ioFVersNum = 0;
		thePB.fileParam.ioFDirIndex = 0;
		if(!(PBGetFInfo(&thePB,false))) temp = thePB.fileParam.ioFlMdDat;
		p2cstr(fileName);
	} else GetDateTime(&temp);
	IUDateString(temp,shortDate,theHeader.date);
	IUTimeString(temp,false,theHeader.time);
	
	result = faccess(fileName,F_GFONTINFO,&temp1);
	if(cmdLineFont != 9999) theBody.font = cmdLineFont;
	else if(!result) theBody.font = HiWord(temp1);
	if(cmdLineSize) theBody.size = cmdLineSize;
	else if(!result >= 0) theBody.size = LoWord(temp1);

	if(cmdLineTab != 9999) theBody.tabWidth = cmdLineTab;
	else if(!(faccess(fileName,F_GTABINFO,&temp1))) theBody.tabWidth = temp1;

}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Calculate and set various values having to do with lineHeight, linesPerPage, header height,
	etc... */
	
#define GetFScaleDisable()	(*((char *) 0x0A63))
void SetLineStuff()
{
	FontInfo	fInfo;
	short		pageHeight;
	Rect		tempRect;
	Boolean		fscaledisable;
	
	if(theHeader.draw) {
		TextFont(theHeader.font);
		TextSize(theHeader.size);
		GetFontInfo(&fInfo);
		theHeader.height = fInfo.ascent + fInfo.descent + fInfo.leading + 4;
	}
	
	fscaledisable = GetFScaleDisable();		/* Get state of font scaling flag */
	SetFScaleDisable(false);				/* Enable font scaling so we get scaled lineheight */
	
	TextFont(theBody.font);
	TextSize(theBody.size);
	GetFontInfo(&fInfo);
	theBody.lineHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
	
	SetFScaleDisable(fscaledisable);		/* Return to previous state of font scaling flag */

	tempRect = GetrPage(thePrintRec);
	pageHeight = tempRect.bottom - tempRect.top - theHeader.height;
	theBody.linesPerPage = pageHeight/theBody.lineHeight;
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Returns the rPage rectangle out of the print record. */
Rect GetrPage(THPrint thePrintRec)
{
	Rect tempR;
	
	tempR = (**thePrintRec).prInfo.rPage;
	if (threeHole) tempR.top += 15;
	
	return (tempR);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* This function takes the print record and forces it into landscape mode */
/* This is sicker than sick.  It depends on the values of completely undocumented bits
	of the print record.  This routine is subject to break at any point in time. */
void ForceLandscape(THPrint thePrintRec)
{
	Rect	tempRect;
	
	/* If the portrait bit of the wDev field of the print record is set (bit 1), then
		rotate the rPaper and rPage rectangles by 90 degrees and finally unset the
		portrait bit to fake the print driver into thinking that the user has selected
		landscape mode.  At the current time (July 1988) both the ImageWriter and 
		LaserWriter use the same bit of the wDev for a portrait/landscape flag.
		As long as this stays the same, this routine will work for both types of printers. */
		
	if((**thePrintRec).prStl.wDev & 0x0002) {
		tempRect.top = (**thePrintRec).rPaper.left;
		tempRect.left = (**thePrintRec).rPaper.top;
		tempRect.bottom = (**thePrintRec).rPaper.right;
		tempRect.right = (**thePrintRec).rPaper.bottom;
		(**thePrintRec).rPaper = tempRect;
		
		tempRect.bottom = (**thePrintRec).prInfo.rPage.bottom;
		(**thePrintRec).prInfo.rPage.bottom = (**thePrintRec).prInfo.rPage.right;
		(**thePrintRec).prInfo.rPage.right = tempRect.bottom;
		
		(**thePrintRec).prInfoPT.rPage = (**thePrintRec).prInfo.rPage;
		
		(**thePrintRec).prStl.wDev ^= 0x0002;
	}
	
	/*
	**	Another completely skanky trick:
	**
	**	If 3-hole paper is used we need to rotate the paper 180 degrees
	**  this is accomplished by setting the horizontal flip and vertical flip
	**  bits in the printX[5] field of the PrintRecord
	*/
	if (threeHole) {
		(**thePrintRec).printX[5] |= 0x0006;
	}
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Draw the page headers */
void DrawHeader(Rect *theRect,short pageNum)
{
	short	oldFont,oldSize,titleWidth,dateWidth,pageWidth,pageCenter;
	char	thePageStr[256];
	
	/* Save the current font and size settings */
	oldFont = thePrPort->gPort.txFont;
	oldSize = thePrPort->gPort.txSize;
	
	/* Set the header font and size and then draw the date/time value left justified */
	TextFont(theHeader.font);
	TextSize(theHeader.size);
	MoveTo(theRect->left+4,theRect->top + theHeader.height-4);
	DrawString(theHeader.date);
	drawstring(" ");
	DrawString(theHeader.time);
	dateWidth = StringWidth(theHeader.date) + StringWidth(theHeader.time) + stringwidth(" ");
	
	/* Draw the page number right justified */
	NumToString((long)pageNum,thePageStr);
	pageWidth = StringWidth(thePageStr) + StringWidth("\pPage ");
	MoveTo(theRect->right - 4 - pageWidth, theRect->top + theHeader.height-4);
	DrawString("\pPage ");
	DrawString(thePageStr);
	
	/* Draw the title centered over the document */
	titleWidth = stringwidth(theHeader.title);
	pageCenter = ((theRect->right - pageWidth - 4) + (theRect->left + dateWidth + 4))/2;
	
	if (titleWidth + pageWidth + dateWidth > theRect->right - theRect->left - 16)
	{
		char tmp_str[256];
		char *first_colon, *last_colon;
		
		first_colon = strchr(theHeader.title, ':');
		last_colon = strrchr(theHeader.title, ':');
		
		if (first_colon != nil && first_colon != last_colon) {
			strncpy(tmp_str, theHeader.title, first_colon - theHeader.title + 1);
			tmp_str[first_colon - theHeader.title + 1] = '\0';
			
			strcat(tmp_str, " ... ");
			strcat(tmp_str, last_colon);
			strcpy(theHeader.title, tmp_str);
			titleWidth = stringwidth(theHeader.title);
		}
	}
	MoveTo(pageCenter - (titleWidth>>1),theRect->top + theHeader.height-4);
	drawstring(theHeader.title);
	
	/* Restore the old font and size settings */
	TextFont(oldFont);
	TextSize(oldSize);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* Draw the page border.  This routine draw either the right or left page border on the paper.
	The border styles are the same as the standard MPW print tool.  Within this routine we also
	draw the page header (if that option has been specified) */
Rect DrawBorder(short whichSide,short pageNum)
{
	Rect	tempRect;
	
	tempRect = GetrPage(thePrintRec);
	ClipRect(&tempRect);
	if(whichSide == left) tempRect.right = ((tempRect.right-tempRect.left) >> 1) - 1;
	if(whichSide == right) tempRect.left = ((tempRect.right-tempRect.left) >> 1) + 1;
	tempRect.bottom -= 1;
	if(theHeader.draw) DrawHeader(&tempRect,pageNum);
	switch(theBody.borderType) {
		case 0:
			if(theHeader.draw) tempRect.top += theHeader.height;
			break;
		case 1:
			FrameRoundRect(&tempRect,10,10);
			if(theHeader.draw) {
				MoveTo(tempRect.left,tempRect.top+theHeader.height);
				LineTo(tempRect.right-1,tempRect.top+theHeader.height);
				tempRect.top += theHeader.height;
			}
			break;
		case 2:
			if(theHeader.draw) tempRect.top += theHeader.height;
			FrameRoundRect(&tempRect,10,10);
			break;
	}
	return(tempRect);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* This routine takes a C string, and then goes through it character by character looking for
	tab characters (0x09).  When it finds one, it figures out how many space characters (0x20)
	should be inserted for that tab.  Two strings are used in this routine, the original, and
	a temporary one, into which the original, and the substituted space characters are copied.
	When the end of the original string is reached, the temp string is copied over the original. */
short Tabs2Spaces(char *theString)
{
	char	tempStr[maxStr];
	char	*inStr,*outStr;
	short	i,chars,spacesToInsert;
	
	inStr = theString;
	outStr = tempStr;
	chars = 0;

	while(*inStr != 0x00) {
		if(*inStr == 0x09) {
			inStr++;
			spacesToInsert = theBody.tabWidth - (chars % theBody.tabWidth);
			chars += spacesToInsert;
			for(i=1;i<=spacesToInsert;i++) *outStr++ = 0x20;
		} else {
			*outStr++ = *inStr++;
			chars++;
		}
	}
	*outStr = 0x00;
	strcpy(theString,tempStr);
	return(chars);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* This routine prints the specified file. */
OSErr PrintFile(FILE *theStream)
{
	Rect		drawRect;
	short		pageSide,i;
	char		tempStr[maxStr];
	Boolean		done = false;
	OSErr		result = noErr;
	short		pageNum = 0;
	long		totalChars = 0;
	long		totalLines = 0;

	/* Open a printing grafPort */
	thePrPort = PrOpenDoc(thePrintRec,nil,nil);
	if(!(result = PrError())) {
		SetLineStuff();
		TextFont(theBody.font);
		TextSize(theBody.size);
					
		/* While we haven't reached the end of the file... */
		while(!done) {
			PrOpenPage(thePrPort,nil);
			if(!(result = PrError())) {
			
				/* Draw the left and right side of each piece of paper */
				for(pageSide=left;pageSide<=right && !done;pageSide++) {
					SpinCursor(1);
					drawRect = DrawBorder(pageSide,++pageNum);
					ClipRect(&drawRect);
					for(i=1;i<theBody.linesPerPage && !done;i++) {
						MoveTo(drawRect.left+3,drawRect.top+(i*theBody.lineHeight));
						if(fgets(tempStr,maxStr,theStream)) {
							totalChars += Tabs2Spaces(tempStr);
							totalLines ++;
							drawstring(tempStr);
						}
						else done = true;
					}
				}
			}
			PrClosePage(thePrPort);
		}
	} else {
		fprintf(stderr,"### Print2 - PrOpenDoc fails, you lose.\n");
		result = 3;
		return (result);
	}
	PrCloseDoc(thePrPort);
	if(printProgress) {
		fprintf(stdout,"Printing \"%s\"... %d characters; %d lines; %d page(s) \n",
		theHeader.title,totalChars,totalLines,pageNum);
		fflush(stdout);
	}
	return(result);
}
/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* This routine takes argc and argv and sets all the options specified on the command line. */
int SetOptions(int argc, char *argv[],short *files)
{
	short	argNum,stemp;
	long	length;
	int		status,temp;
	char	*badOpt = "### %s - \"%s\" is not a valid option\n";
	char	*badVal = "### %s - Usage error: %s %s (invalid value)\n";
	
	for(argNum=1;argNum<argc;argNum++) {
		length = strlen(argv[argNum]);
		if(*argv[argNum] != '-') argv[++(*files)] = argv[argNum];
		else switch(tolower(*(argv[argNum]+1))) {
		
			/* Three hole paper? */
			case '3':
				if(length == 2) threeHole = true;
				else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
			
			/* Border style */
			case 'b':
				if(length == 2) theBody.borderType = 1;
				else if(length == 3 && (*(argv[argNum]+2)) == '2') theBody.borderType = 2;
				else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
			
			/* Number of copies */
			case 'c':
				if(length == 2 || (length == 7 && !(strcmp(argv[argNum],"-copies")))) {
					temp = atol(argv[++argNum]);
					if(temp >= 1 && temp <= 100) numCopies = temp;
					else {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Font to use */	
			case 'f':
				if(length == 2 || (length == 5 && !(strcmp(argv[argNum],"-font")))) {
					getfnum(argv[++argNum],&cmdLineFont);
					if(!cmdLineFont) {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Print headers (-h), header font (-hf[ont]), and header size (-hs[ize]) */	
			case 'h':
				if(length == 2) theHeader.draw = true;
				else 
				if((length == 3 && (*(argv[argNum]+2)) == 'f') ||
				   (length == 6 && !(strcmp(argv[argNum],"-hfont")))) {
					getfnum(argv[++argNum],&stemp);
					if(stemp) theHeader.font = stemp;
					else {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				}
				else 
				if((length == 3 && (*(argv[argNum]+2)) == 's') ||
				   (length == 6 && !(strcmp(argv[argNum],"-hsize")))) {
					temp = atol(argv[++argNum]);
					if(temp > 2 && temp < 37) theHeader.size = temp;
					else {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Use modification date in header (rather than current date) */
			case 'm':
				if(length == 3 && (*(argv[argNum]+2)) == 'd') theHeader.modDate = true;
				else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Allow the "slacker" to redeem himself */
			case 'n':
				if(length == 8 && !(strcmp(argv[argNum],"-noslack"))) {
					slack = false;
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Write progress information */
			case 'p':
				if(length == 2) {
					printProgress = true;
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Set the body font size */
			case 's':
				if(length == 2 || (length == 5 && !(strcmp(argv[argNum],"-size")))) {
					temp = atol(argv[++argNum]);
					if(temp > 2 && temp < 37) cmdLineSize = temp;
					else {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* Set the tab width */
			case 't':
				if(length == 2 || (length == 5 && !(strcmp(argv[argNum],"-tabs")))) {
					temp = atol(argv[++argNum]);
					if(temp >= 0 && temp <= 16) cmdLineTab = temp;
					else {
						fprintf(stderr,badVal,argv[0],argv[0],argv[argNum-1]);
						status = 1;
					}
				} else {
					fprintf(stderr,badOpt,argv[0],argv[argNum]);
					status = 1;
				}
				break;
				
			/* A bad (non-supported) option */
			default:
				fprintf(stderr,badOpt,argv[0],argv[argNum]);
				status = 1;
				break;
		}
	}
	return(status);
}

/*
** Skank to get print manager to use document name (TN #149)
*/
void
PrValidateAndName(THPrint tPR, char *fname)
{
#if 0
	Rect r;
	
	if (phonyWindow != nil) DisposeWindow(phonyWindow);
	phonyWindow = nil;
	
	SetRect(&r, 32000, 32000, 32010, 32010); /* Pretty far off-screen */
	phonyWindow = newwindow(nil, &r, fname, true, plainDBox, (WindowPtr) -1, false, nil);

	PrValidate(tPR);
	
	if (phonyWindow != nil) DisposeWindow(phonyWindow);
	phonyWindow = nil;
	
#else

	char   *username, *jobName;
	char   tmp[256];
	
	/* 
	**	Special treatment for the slacker (once in a while...(20%))
	*/
	username = getenv("User");
	if (slack && username != nil && !strcmp(username, "Paul Mercer") && (TickCount()%5 == 0) ) {
		strcpy(tmp, "SLACKER! ");
		strcat(tmp, fname);
	} else {
		strcpy(tmp, fname);
	}
	c2pstr(tmp);
	jobName = tmp;

	if (jobNameH != nil) DisposHandle(jobNameH);
	
	/*
	**	Another completely skanky trick:
	**
	**	Jam the PrintRecord with our jobName
	**	this is accomplished by placing a handle to the 
	**  name in the printX[3] and [4] fields of the PrintRecord
	**
	**	This is sicker than sick.  It depends on the values of 
	**	completely undocumented bits of the print record.
	**
	**	This routine is subject to break at any point in time.
	**
	**	If anything fails, just fall through
	*/
	jobNameH = NewString(jobName);
	if (jobNameH != nil) {
		*((Handle *) &(*tPR)->printX[3]) = jobNameH;
	}
	
	PrValidate(tPR);
	
#endif
}

/*-------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------*/
/* The main routine of the tool. */
int main(int argc, char *argv[])
{
	short	argNum,files,i;
	FILE	*theStream;
	char	errorBuffer[256];
	int		status;

	files = 0;
	InitGraf(&qd.thePort);
	InitCursorCtl(nil);
	SetDefaults();
	status = SetOptions(argc,argv,&files);
	if(printProgress) DoAbout();
	
	if(!(thePrintRec = (THPrint)NewHandle(sizeof(TPrint)))) {
		fprintf(stderr,"### %s - Unable to allocate a print record \n", argv[0]);
		fprintf(stderr,"# %s\n", GetSysErrText(MacOSErr,errorBuffer));
		status = 3;
	}
	else {
		PrOpen();
		if(PrError() != 0) {
			fprintf(stderr,"### %s - PrOpen fails, check that a printer is selected.\n", argv[0]);
			DisposHandle((Handle) thePrintRec);
			status = 3;
			return (status);
		}
		if(files == 0) {
			if(ioctl(fileno(stdin),FIOINTERACTIVE,nil)) 
				for(i=1;i<=numCopies;i++) {
					PrintDefault(thePrintRec);
					ForceLandscape(thePrintRec);
					
					/*
					** Validate and Set Document Name
					*/
					PrValidateAndName(thePrintRec, "Dev:Stdin");
					
					PrintFile(stdin);
				}
			else {
				fprintf(stderr,"### %s - Cannot print input from the console\n", argv[0]);
				status = 2;
			}
		} else {
			for(argNum=1;argNum<=files;argNum++) {
				if(theStream = fopen(argv[argNum],"r")) {
				
					PrintDefault(thePrintRec);
					SetFileStuff(argv[argNum]);

					ForceLandscape(thePrintRec);
					
					/*
					** Validate and Set Document Name
					*/
					PrValidateAndName(thePrintRec, argv[argNum]);
					
					for(i=1;i<=numCopies;i++) PrintFile(theStream);
					fclose(theStream);
				} else {
					fprintf(stderr,"### %s - Unable to open the file: \"%s\"\n", argv[0], argv[argNum]);
					fprintf(stderr,"# %s\n", GetSysErrText(MacOSErr,errorBuffer));
					status = 2;
				}
			}
		}
		PrClose();
		DisposHandle((Handle) thePrintRec);
	}
	return(status);
}
/*-------------------------------------------------------------------------------------------------*/
